package tests;

import static org.junit.Assert.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
import java.util.UUID;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import sourceFiles.CentralComputer;
import sourceFiles.ChildEntry;
import sourceFiles.Ride;
import sourceFiles.RideState;

import Exceptions.InvalidAgeParam;
import Exceptions.InvalidCapacity;
import Exceptions.InvalidChildID;
import Exceptions.InvalidHeightParam;
import Exceptions.InvalidRideId;
import Exceptions.InvalidRideName;
import Exceptions.TicketDoesntExist;
import Exceptions.XMLRidesParserException;
import Exceptions.CentralComputerExceptions.ChildAgeDoesntMatch;
import Exceptions.CentralComputerExceptions.ChildDoesntHaveTicket;
import Exceptions.CentralComputerExceptions.ChildHeightDoesntMatch;
import Exceptions.CentralComputerExceptions.ChildIDDoesntExist;
import Exceptions.CentralComputerExceptions.RideIDDoesntExist;
import RideExceptions.ChildAlreadyInRideException;
import RideExceptions.ChildNotInRideException;
import RideExceptions.RideActiveException;
import RideExceptions.RideInactiveException;
//import Stubs.CentralComputerStub3;
/**
 * @author LASO-Team
 *
 */
public class RideTestCC1 {

	static private String masterXMLFilePath;
	static private String copyXMLFilePath;
	static private int numOfInitialRides;
	
	static Random random;
	private static final int RANDOM_TEST_SIZE = 7;
	private static final int[] EDGE_OF_LEGAL_INT_VALUES = { 1, 2 };
	private static final int[] EDGE_OF_ILLEGAL_INT_VALUES = { -1, 0 };
	private static final int TEST_SIZE = RANDOM_TEST_SIZE
			+ EDGE_OF_LEGAL_INT_VALUES.length;
	private static final int MAX_RANDOM = 99;
	private static final String IN_PROJECT_PATH_TO_TESTS = "\\src\\tests";

	static private int[] legalChildID;
	static private String[] legalRideNames;
	static private int[] legalRideID;
	static private int[] legalMaxCapacity;
	static private int[] legalMinAge;
	static private int[] legalMinHeight;
	static private boolean[] isExtremeRide;
	static private int[] illegalChildID;
	// static private int[] illegalRideID;
	static private int[] illegalMaxCapacity;
	static private int[] illegalMinAge;
	static private int[] illegalMinHeight;

	static private int[] legalGuardianIDs;
	static private int[] illegalGuardianIDs;
		
	static private int[] nonExistingChildID;
	static private int[] nonExistingLegalGuardianIDs;
	
	static private int[] billingInfo;
	
	// static private int[] nonExistingRideID;

//	static private CentralComputerStub3 centralComputerStub;
	static private CentralComputer cc;
//	static private LinkedList<Ride> rides;
//	static private LinkedList<ChildEntry> children;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		assertTrue(EDGE_OF_LEGAL_INT_VALUES.length == EDGE_OF_ILLEGAL_INT_VALUES.length);
		String currentPath = new java.io.File(".").getCanonicalPath();
		currentPath = currentPath + IN_PROJECT_PATH_TO_TESTS;
		masterXMLFilePath = currentPath + "\\TestsMaster.xml";
		copyXMLFilePath = currentPath + "\\results\\ResultsIntegrationRideCC.xml";
		random = new Random();
		LinkedList<Integer> legalChildIDList = new LinkedList<Integer>();
		LinkedList<Integer> legalRideIDList = new LinkedList<Integer>();
		LinkedList<Integer> legalMaxCapacitiesList = new LinkedList<Integer>();
		LinkedList<Integer> legalMinAgesList = new LinkedList<Integer>();
		LinkedList<Integer> legalMinHeightsList = new LinkedList<Integer>();
		LinkedList<Integer> legalGuardianIDsList = new LinkedList<Integer>();
		LinkedList<Integer> illegalChildIDsList = new LinkedList<Integer>();
		// LinkedList<Integer> illegalRideIDsList = new LinkedList<Integer>();
		LinkedList<Integer> illegalMaxCapacitiesList = new LinkedList<Integer>();
		LinkedList<Integer> illegalMinAgesList = new LinkedList<Integer>();
		LinkedList<Integer> illegalMinHeightsList = new LinkedList<Integer>();
		LinkedList<Integer> illegalGuardianIDsList = new LinkedList<Integer>();
		

		for (int i = 0; i < EDGE_OF_LEGAL_INT_VALUES.length; i++) {
			legalChildIDList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			legalRideIDList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			legalMaxCapacitiesList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			legalMinAgesList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			legalMinHeightsList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			illegalChildIDsList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			// illegalRideIDsList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			illegalMaxCapacitiesList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			illegalMinAgesList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			illegalMinHeightsList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			
			legalGuardianIDsList.add(EDGE_OF_LEGAL_INT_VALUES[i]);
			illegalGuardianIDsList.add(EDGE_OF_ILLEGAL_INT_VALUES[i]);
			
		}
		for (int i = 0; i < RANDOM_TEST_SIZE; i++) {
			int newRandomID = random.nextInt(MAX_RANDOM) + 1;
			while (legalChildIDList.contains(newRandomID)) {
				newRandomID = random.nextInt(MAX_RANDOM) + 1;
			}
			legalChildIDList.add(newRandomID);
			legalGuardianIDsList.add(newRandomID);
			legalRideIDList.add(newRandomID);
			legalMaxCapacitiesList.add(random.nextInt(MAX_RANDOM) + 2);
			legalMinAgesList.add(random.nextInt(MAX_RANDOM) + 2);
			legalMinHeightsList.add(random.nextInt(MAX_RANDOM) + 2);
			illegalChildIDsList.add(-random.nextInt(MAX_RANDOM));
			// illegalRideIDsList.add(-random.nextInt(MAX_RANDOM));
			illegalMaxCapacitiesList.add(-random.nextInt(MAX_RANDOM));
			illegalMinAgesList.add(-random.nextInt(MAX_RANDOM));
			illegalMinHeightsList.add(-random.nextInt(MAX_RANDOM));
		}
		legalChildID = new int[TEST_SIZE];
		legalRideID = new int[TEST_SIZE];
		legalRideNames = new String[TEST_SIZE];
		legalMaxCapacity = new int[TEST_SIZE];
		legalMinAge = new int[TEST_SIZE];
		legalMinHeight = new int[TEST_SIZE];
		isExtremeRide = new boolean[TEST_SIZE];

		illegalChildID = new int[TEST_SIZE];
		legalGuardianIDs = new int[TEST_SIZE];
		// illegalRideID = new int[TEST_SIZE];
//		illegalGuardianIDs = new int[TEST_SIZE];
		illegalMaxCapacity = new int[TEST_SIZE];
		illegalMinAge = new int[TEST_SIZE];
		illegalMinHeight = new int[TEST_SIZE];
		nonExistingChildID = new int[TEST_SIZE];
		// nonExistingRideID = new int[TEST_SIZE];
		billingInfo = new int[TEST_SIZE];

		for (int i = 0; i < TEST_SIZE; i++) {

			legalChildID[i] = legalChildIDList.get(i);
			legalGuardianIDs[i] = legalGuardianIDsList.get(i);

			legalRideID[i] = legalRideIDList.get(i);
			legalRideNames[i] = UUID.randomUUID().toString();
			legalMaxCapacity[i] = legalMaxCapacitiesList.get(i);
			legalMinAge[i] = legalMinAgesList.get(i);
			legalMinHeight[i] = legalMinHeightsList.get(i);
			isExtremeRide[i] = random.nextBoolean();

			illegalChildID[i] = illegalChildIDsList.get(i);
			// illegalRideID[i] = illegalRideIDsList.get(i);
			illegalMaxCapacity[i] = illegalMaxCapacitiesList.get(i);
			illegalMinAge[i] = illegalMinAgesList.get(i);
			illegalMinHeight[i] = illegalMinHeightsList.get(i);

			int newRandomID = random.nextInt(MAX_RANDOM) + 1;
			while (legalChildIDList.contains(newRandomID)) {
				newRandomID = random.nextInt(MAX_RANDOM) + 1;
			}
			nonExistingChildID[i] = newRandomID;
			billingInfo[i] = random.nextInt();
			// nonExistingRideID[i] = newRandomID;
		}
	}

	@Before
	public void setUp() throws XMLRidesParserException, InvalidRideName, InvalidCapacity, InvalidAgeParam, InvalidHeightParam, IOException {
		copySourceFile();
		cc = new CentralComputer(copyXMLFilePath);
		numOfInitialRides = cc.getRidesList().size();

//		rides = new LinkedList<Ride>();
		for (int i = 0; i < TEST_SIZE; i++) {
			cc.createRide(legalRideNames[i], isExtremeRide[i], legalMaxCapacity[i], legalMinAge[i], legalMinHeight[i]);
			
//			centralComputerStub.getRideIDList().add(legalRideID[i]);
//			centralComputerStub.getMaxCapacityList().add(legalMaxCapacity[i]);
//			centralComputerStub.getIsExtremeRideList().add(isExtremeRide[i]);
//			centralComputerStub.getMinAgeList().add(legalMinAge[i]);
//			centralComputerStub.getMinHeightList().add(legalMinHeight[i]);
//			centralComputerStub.getChildIDList().add(legalChildID[i]);
//			rides.add(new Ride(legalRideID[i], legalMaxCapacity[i],
//					legalMinAge[i], legalMinHeight[i], legalRideNames[i],
//					cc));
		}
		//numOfInitialRides = cc.getRidesList().size();
//		children = new LinkedList<ChildEntry>();
	}

	private void copySourceFile() throws FileNotFoundException, IOException {
		InputStream inStream = null;
		OutputStream outStream = null;

		File afile = new File(masterXMLFilePath);
		File bfile = new File(copyXMLFilePath);

		inStream = new FileInputStream(afile);
		outStream = new FileOutputStream(bfile);

		byte[] buffer = new byte[1024];

		int length;
		// copy the file content in bytes
		while ((length = inStream.read(buffer)) > 0) {

			outStream.write(buffer, 0, length);
		}
		inStream.close();
		outStream.close();
	}

	/**
	 * This method tests that we cannot alter a ride to have a capacity less
	 * than 1.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testConfigRideParams1() throws Exception {
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				cc.getRidesList().get(i).configRideParams(illegalMaxCapacity[i],
						legalMinAge[i], legalMinHeight[i]);
				fail("tried to update a ride with an illegalMaxCapacity[" + i
						+ " = " + illegalMaxCapacity[i]);
			} catch (InvalidCapacity e) {
			}
		}
	}

	/**
	 * This method checks the we cannot alter a ride with minimal age less than
	 * 1.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testConfigRideParams2() throws Exception {

		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				cc.getRidesList().get(i).configRideParams(legalMaxCapacity[i],
						illegalMinAge[i], legalMinHeight[i]);
				fail("tried to update a ride with an illegalMinAge[" + i
						+ " = " + illegalMinAge[i]);
			} catch (InvalidAgeParam e) {
			}
		}
	}

	/**
	 * This method tests that we cannot alter a ride with height less than 1.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testConfigRideParams3() throws Exception {
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				cc.getRidesList().get(i).configRideParams(legalMaxCapacity[i],
						legalMinAge[i], illegalMinHeight[i]);
				fail("tried to update a ride with an illegalMinHeight[" + i
						+ " = " + illegalMinHeight[i]);
			} catch (InvalidHeightParam e) {
			}
		}
	}

	/**
	 * This method tests that child cannot enter a ride with it's entrance gate
	 * closed
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildEntersRide1() throws Exception {
		Ride ride;
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				ride = (Ride) cc.getRidesList().get(i);
				ride.getEntranceGate().closeGate();
				ride.childEntersRide(legalChildID[i]);
				fail("tried enter a child when Entrance gate is closed");
			} catch (RideActiveException e) {
			}
		}
	}

	/**
	 * This method tests that child ID cannot be smaller than 1.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildEntersRide2() throws Exception {
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				cc.getRidesList().get(i).childEntersRide(illegalChildID[i]);
				fail("tried enter a child with an  illegalChildID[" + i + " = "
						+ illegalChildID[i]);
			} catch (InvalidChildID e) {
			}
		}
	}

	/**
	 * This method tests that a child that isn't registered to the system cannot
	 * enter the ride.
	 */
	@Test
	public void testChildEntersRide3() throws Exception {
		for (int i = 0; i < TEST_SIZE; i++) {

			try {
				cc.getRidesList().get(i).childEntersRide(nonExistingChildID[i]);
				fail("tried enter a child with a nonExistingChildID[" + i
						+ " = " + nonExistingChildID[i]);
			} catch (ChildIDDoesntExist e) {
			}
		}
	}

	/**
	 * This method tests that a child with age that isn't up to the
	 * specifications of the ride cannot enter the ride.
	 */
	@Test
	public void testChildEntersRide4() throws Exception {
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);
		for (int i = 2; i < TEST_SIZE; i++) {
			// adding children that will be to young to enter the ride. buys tickets for the relevant ride
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i] - 1, legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
		}
		Ride ride;
		for (int i = 2; i < TEST_SIZE; i++) {
			try {
				if (legalMinAge[i] == 1) {
					continue; // skip rides that will be closed for the next
								// child to enter (not relevant for this test)
				}
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				ride.childEntersRide(legalChildID[i]);
				fail("tried enter a child with an  legalMinAge[" + i + " = "
						+ (legalMinAge[i] - 1)
						+ " that is smaller than the minAge " + cc.getRidesList().get(i).getMinimumAge()
						+ " allowed in the ride");
			} catch (ChildAgeDoesntMatch e) {
			}
		}
	}

	/**
	 * This method tests that a child with height that isn't up to the
	 * specifications of the ride cannot enter the it.
	 */
	@Test
	public void testChildEntersRide5() throws Exception {
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);
		for (int i = 2; i < TEST_SIZE; i++) {
			// adding children that will be to short to enter the ride. buys tickets for the relevant ride
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i] - 1);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
		}
		Ride ride;
		for (int i = 2; i < TEST_SIZE; i++) {
			try {
				if (legalMinHeight[i] == 1) {
					continue; // skip rides that will be closed for the next
								// child to enter (not relevant for this test)
				}
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				ride.childEntersRide(legalChildID[i]);
				fail("tried enter a child with an  legalMinHeight[" + i + " = "
						+ (legalMinHeight[i] - 1)
						+ " that is smaller than the minAge "
						+ legalMinHeight[i] + " allowed in the ride");
			} catch (ChildHeightDoesntMatch e) {
			}
		}
	}

	/**
	 * This method tests that if a child doesn't have a ticket to the ride he
	 * cannot enter the ride.
	 */
	@Test
	public void testChildEntersRide6() throws Exception {
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);
		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will not have tickets for the relevant ride
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
		}
		Ride ride;
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				ride.childEntersRide(legalChildID[i]);
				fail("tried enter a child without a ticket");
			} catch (TicketDoesntExist e) {
			}
		}
	}

	/**
	 * This method tests that a child matching all the requirements can enter
	 * the ride
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildEntersRide7() throws Exception {
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);
		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);

		}
		Ride ride;
		for (int i = 0; i < TEST_SIZE; i++) {
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childEntersRide(legalChildID[i]);
		}
	}

	/**
	 * This method tests that cannot enter a ride if he's already inside
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildEntersRide8() throws Exception {
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);
		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);

		}
		Ride ride;
		for (int i = 0; i < TEST_SIZE; i++) {
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childEntersRide(legalChildID[i]);
		}
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				if (legalMaxCapacity[i] == 1) {
					continue; // skip rides that will be closed for the next
								// child to enter (not relevant for this test)
				}
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				ride.childEntersRide(legalChildID[i]);
				fail("tried enter a child with an  legalChildID[" + i + " = "
						+ legalChildID[i] + " that is already in the ride");
			} catch (ChildAlreadyInRideException e) {
			}
		}
	}

	/**
	 * This method tests that a child can exit the ride successfully
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildExitsRide1() throws Exception {

//		LinkedList<Ride>rides = new LinkedList<Ride>();
		Ride ride;
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);

		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childEntersRide(legalChildID[i]);
		}
		boolean areGatesEntranceOpened = true;
		do {
			Thread.sleep(1000);
			for (int i = 0; i < TEST_SIZE; i++) {
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				if (i > 0) {
					areGatesEntranceOpened = ride.getEntranceGate()
							.IsGateOpened() | areGatesEntranceOpened;
				} else {
					areGatesEntranceOpened = ride.getEntranceGate()
							.IsGateOpened();
				}
			}
		} while (areGatesEntranceOpened);
		for (int i = 0; i < TEST_SIZE; i++) {
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childExitsRide(legalChildID[i]);
		}
	}

	/**
	 * This method a child that entered the ride cannot exit the ride while the
	 * ride can admit more children (they are locked in! Muhahahah!!)
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildExitsRide2() throws Exception {

		Ride ride;
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);

		for (int i = 2; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childEntersRide(legalChildID[i]);
		}

		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				if (legalMaxCapacity[i] == 1) {
					continue; // skip ride which will be closed by entering 1
								// child to them
				}
				ride.childExitsRide(legalChildID[i]);
				fail("tried to leave a ride with a child with a  legalChildID["
						+ i + "] = " + legalChildID[i]
						+ " while ride can admit more children");
			} catch (RideInactiveException e) {
			}
		}
	}

	/**
	 * This method a child that a child that leaves a ride must have entered the
	 * ride before
	 * 
	 * @throws Exception
	 */
	@Test
	public void testChildExitsRide3() throws Exception {

		Ride ride;
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);

		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			ride.childEntersRide(legalChildID[i]);
		}

		boolean areGatesEntranceOpened = true;
		do {
			Thread.sleep(1000);
			for (int i = 0; i < TEST_SIZE; i++) {
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				if (i > 0) {
					areGatesEntranceOpened = ride.getEntranceGate()
							.IsGateOpened() | areGatesEntranceOpened;
				} else {
					areGatesEntranceOpened = ride.getEntranceGate()
							.IsGateOpened();
				}
			}
		} while (areGatesEntranceOpened);
		for (int i = 0; i < TEST_SIZE; i++) {
			try {
				ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
				ride.childExitsRide(nonExistingChildID[i]);
				fail("tried to leave a ride with a child with a nonExistingChildID["
						+ i
						+ "] = "
						+ nonExistingChildID[i]
						+ " that was not in the ride");
			} catch (ChildNotInRideException e) {
			}
		}
	}

	/**
	 * This method a child that a child that leaves a ride must have entered the
	 * ride before
	 * 
	 * @throws Exception
	 */
	@Test
	public void testRideCycle() throws Exception {
		Ride ride;
		cc.addGuardian(legalGuardianIDs[2], billingInfo[2]);

		for (int i = 0; i < TEST_SIZE; i++) {
			// adding children that will be approved to enter the ride in the
			cc.addChildToGuardian(legalGuardianIDs[2], legalChildID[i], legalMinAge[i], legalMinHeight[i]);
			cc.buyingProcess(cc.getRidesList().get(i+numOfInitialRides).getRideID(), legalGuardianIDs[2], legalChildID[i]);
			ride = (Ride)cc.getRidesList().get(i+numOfInitialRides);
			//ride.childEntersRide(legalChildID[i]);
		}

		ride = (Ride)cc.getRidesList().get(2+numOfInitialRides);
		try {
			for (int i = 0; i < 1000; i++) {
				Thread.sleep(10);
				
				assertTrue("" + i, ride.getEntranceGate().IsGateOpened());
				assertTrue(!ride.getExitGate().IsGateOpened());
				assertTrue(ride.getState() == RideState.STANDBY);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
		ride = (Ride)cc.getRidesList().get(2+numOfInitialRides);
		
		ride.childEntersRide(legalChildID[2]);
		while(ride.getEntranceGate().IsGateOpened()){
			Thread.sleep(1000);
		}
		for (int i = 0; i < 1000; i++) {
			assertTrue(!ride.getEntranceGate().IsGateOpened());
			assertTrue(ride.getExitGate().IsGateOpened());
			assertTrue(ride.getState() == RideState.RUNNING);
			Thread.sleep(10);
		}
		ride.childExitsRide(legalChildID[2]);
		for (int i = 0; i < 1000; i++) {
			Thread.sleep(10);
			assertTrue(ride.getEntranceGate().IsGateOpened());
			assertTrue(!ride.getExitGate().IsGateOpened());
			assertTrue(ride.getState() == RideState.STANDBY);
		}
	}

}
